package com.atguigu.tingshu.search.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.CategoryFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.PinYinUtils;
import com.atguigu.tingshu.model.album.*;
import com.atguigu.tingshu.model.search.AlbumInfoIndex;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.model.search.SuggestIndex;
import com.atguigu.tingshu.query.search.AlbumIndexQuery;
import com.atguigu.tingshu.search.repository.AlbumIndexRepository;
import com.atguigu.tingshu.search.repository.SuggestIndexRepository;
import com.atguigu.tingshu.search.service.SearchService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.atguigu.tingshu.vo.search.AlbumInfoIndexVo;
import com.atguigu.tingshu.vo.search.AlbumSearchResponseVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.suggest.Completion;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;


@Slf4j
@Service
@SuppressWarnings({"all"})
public class SearchServiceImpl implements SearchService {

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private CategoryFeignClient categoryFeignClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private AlbumIndexRepository albumIndexRepository;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Autowired
    private SuggestIndexRepository suggestIndexRepository;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * @author WeakMoon
     * @date 2025/03/05 16:19:21
     * 获取排行榜
     */
    @Override
    public List<AlbumInfoIndex> findRankingList(Long category1Id, String ranking) {
        List<AlbumInfoIndex> list = (List<AlbumInfoIndex>) redisTemplate.opsForHash().get(RedisConstant.RANKING_KEY_PREFIX + category1Id, ranking);
        return list;
    }


    /**
     * @author WeakMoon
     * @date 2025/03/04 21:43:25
     * 更新排行榜
     */
    @Override
    public void updateLatelyAlbumRanking() {
        // 调用分类服务获取所有一级分类
        Result<List<BaseCategory1>> baseCategory1Result = categoryFeignClient.findAllCategory1();

        // 确保调用成功
        Assert.notNull(baseCategory1Result,"远程调用获取一级分类失败");
        List<BaseCategory1> baseCategory1List = baseCategory1Result.getData();

        // 确保数据不为空
        Assert.notNull(baseCategory1List,"远程调用一级分类失败");

        // 遍历每个一级分类
        for (BaseCategory1 baseCategory1 : baseCategory1List) {
            // 声明一个数组或集合来存储五个排序的维度
            String[] rankingDimensionArray = new String[]{"hotScore", "playStatNum", "subscribeStatNum", "buyStatNum", "commentStatNum"};

            // 遍历每个排名维度
            for (String rankingDimension : rankingDimensionArray) {
                SearchResponse<AlbumInfoIndex> searchResponse = null;
                try {
                    // 执行dsl语句查询数据
                    searchResponse = elasticsearchClient.search(s -> s.index("albuminfo")
                                    .query(q -> q.term(t -> t.field("category1Id").value(baseCategory1.getId())))
                                    .sort(st -> st.field(f -> f.field(rankingDimension).order(SortOrder.Desc)))
                            ,AlbumInfoIndex.class);

                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                // 收集查询结果

                List<AlbumInfoIndex> albumInfoIndexList = searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList());
                // 将结果存入Redis
                redisTemplate.opsForHash().put(RedisConstant.RANKING_KEY_PREFIX + baseCategory1.getId(),rankingDimension,albumInfoIndexList);
            }
        }
    }

    /**
     * @author WeakMoon
     * @date 2025/02/28 19:10:15
     * 自动补全
     */
    @Override
    public List<String> completeSuggest(String keyword) {
        // 初始化搜索响应对象 根据用户输入的检索数据，从es中获取数据集合；并返回给用户
        SearchResponse<SuggestIndex> searchResponse = null;

        try {
            // 执行 Elasticsearch 搜索，使用建议功能进行关键词补全
            searchResponse = elasticsearchClient.search(s -> s.index("suggestinfo")
                            .suggest(s1 -> s1.suggesters("keyword-suggest", s2 -> s2.prefix(keyword).completion(c -> c
                                            .field("keyword")
                                            .skipDuplicates(true)
                                            .fuzzy(f -> f.fuzziness("auto")).size(10)))
                                    .suggesters("keywordPinyin-suggest", s2 -> s2.prefix(keyword).completion(c -> c
                                            .field("keywordPinyin")
                                            .skipDuplicates(true)
                                            .fuzzy(f -> f.fuzziness("auto")).size(10)))
                                    .suggesters("keywordSequence-suggest", s2 -> s2.prefix(keyword).completion(c -> c
                                            .field("keywordSequence")
                                            .skipDuplicates(true)
                                            .fuzzy(f -> f.fuzziness("auto")).size(10)))

                            )
                    , SuggestIndex.class);
        } catch (IOException e) {
            // 捕获异常并将其转换为运行时异常
            throw new RuntimeException(e);
        }

        // 获取集合数据; 数据都在options;
        List<String> list = new ArrayList<>();

        list.addAll(getSuggestionTitle(searchResponse,"keyword-suggest"));
        list.addAll(getSuggestionTitle(searchResponse,"keywordPinyin-suggest"));
        list.addAll(getSuggestionTitle(searchResponse,"keywordSequence-suggest"));

        // 返回结果数据
        return list;
    }

    /**
     * 获取建议标题
     * 根据搜索响应和建议名称，提取出建议列表中的标题
     * 如果建议列表为空，则返回空列表
     *
     * @param searchResponse 搜索响应对象，包含建议信息
     * @param suggest 建议名称，用于获取特定的建议列表
     * @return 返回一个字符串集合，包含建议列表中的标题
     */
    private Collection<String> getSuggestionTitle(SearchResponse<SuggestIndex> searchResponse, String suggest) {
        // 获取提词库中的数据
        List<Suggestion<SuggestIndex>> suggestionList = searchResponse.suggest().get(suggest);

        // 检查集合是否不为空
        if (!CollectionUtils.isEmpty(suggestionList)){

            // 循环遍历集合
            for (Suggestion<SuggestIndex> suggestIndexSuggestion : suggestionList) {
                // 获取数据
                List<String> list = suggestIndexSuggestion.completion().options().stream().map(option -> {
                    String title = option.source().getTitle();
                    return title;
                }).collect(Collectors.toList());

                // 返回结果数据
                return list;
            };
        }

        // 如果为空，返回一个空的列表
        return new ArrayList<>();
    }

    /**
     * @author WeakMoon
     * @date 2025/02/28 16:25:14
     * 展示频道页数据
     */
    @Override
    public List<Map<String, Object>> channel(Long category1Id) {
        // 调用categoryFeignClient获取一级分类对应的三级分类信息
        Result<List<BaseCategory3>> baseCategory3ResultList = categoryFeignClient.findTopBaseCategory3(category1Id);

        // 断言三级分类信息不为空，否则抛出异常
        Assert.notNull(baseCategory3ResultList,"远程调用获取三级分类信息失败");
        List<BaseCategory3> baseCategory3List = baseCategory3ResultList.getData();

        // 将三级分类信息转换为Map，以便后续使用
        Map<Long, BaseCategory3> category3Map = baseCategory3List.stream().collect(Collectors.toMap(BaseCategory3::getId, baseCategory3 -> baseCategory3));

        // 断言三级分类信息不为空，否则抛出异常
        Assert.notNull(baseCategory3List,"远程调用失败");
        List<Long> category3IdList = baseCategory3List.stream().map(BaseCategory3::getId).collect(Collectors.toList());

        // 准备搜索所需的FieldValue列表
        List<FieldValue> valueList = category3IdList.stream().map(category3Id -> FieldValue.of(category3Id)).collect(Collectors.toList());
        SearchResponse<AlbumInfoIndex> searchResponse = null;
        try {
            // 使用elasticsearchClient进行搜索，获取按三级分类聚合的专辑信息
            searchResponse = elasticsearchClient.search(s -> s.index("albuminfo").query(q -> q.bool(b -> b.filter(f -> f
                                        .terms(t -> t.field("category3Id").terms(t1 -> t1.value(valueList))))))
                                .aggregations("agg_category3Id", a -> a.terms(t -> t.field("category3Id"))
                                        .aggregations("agg_topSix", a1 -> a1.topHits(t1 -> t1.size(6).sort(st -> st.field(f -> f.field("hotScore").order(SortOrder.Desc))))))
                        , AlbumInfoIndex.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 从结果集中专辑集合数据; 从聚合中获取数据
        Aggregate aggregate = searchResponse.aggregations().get("agg_category3Id");

        // 处理搜索结果，组装返回数据 创建一个list<map> 集合
        List<Map<String, Object>> listMap = aggregate.lterms().buckets().array().stream().map(bucket -> {
            Map<String, Object> map = new HashMap<>();

            //  获取三级分类Id
            long category3Id = bucket.key();

            //  获取专辑集合数据
            Aggregate aggTopSix = bucket.aggregations().get("agg_topSix");
            List<AlbumInfoIndex> albumInfoIndexList = aggTopSix.topHits().hits().hits().stream().map(hit -> {
                //  获取source 数据;
                String data = hit.source().toString();
                AlbumInfoIndex albumInfoIndex = JSONObject.parseObject(data, AlbumInfoIndex.class);
                return albumInfoIndex;
            }).collect(Collectors.toList());

            //  根据三级分类Id 获取到三级分类对象
            map.put("baseCategory3", category3Map.get(category3Id));
            map.put("list", albumInfoIndexList);

            return map;
        }).collect(Collectors.toList());

        // 返回结果数据
        return listMap;
    }



    /**
     * @author WeakMoon
     * @date 2025/02/25 18:56:23
     * 专辑上架
     */
    @Override
    public void upperAlbum(Long albumId) {
        // 初始化专辑信息索引对象
        // 需要远程调用获取数据，并将数据赋值给AlbumInfoIndex
        AlbumInfoIndex albumInfoIndex = new AlbumInfoIndex();

        // 异步获取专辑信息
        CompletableFuture<AlbumInfo> albumInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 调用远程接口获取专辑信息
            Result<AlbumInfo> infoResult = albumInfoFeignClient.getAlbumInfo(albumId);
            // 断言远程调用结果不为空
            Assert.notNull(infoResult, "远程调用失败");

            // 提取专辑信息
            AlbumInfo albumInfo = infoResult.getData();
            // 断言专辑信息不为空
            Assert.notNull(albumInfo, "远程调用albumInfo失败");

            // 复制专辑信息到索引对象
            BeanUtils.copyProperties(albumInfo, albumInfoIndex);
            // 转换专辑属性值列表
            // 通过专辑Id 查找属性Id ，属性值Id;
            List<AlbumAttributeValue> albumAttributeValueVoList = albumInfo.getAlbumAttributeValueVoList();
            // 循环遍历
            List<AttributeValueIndex> attributeValueIndexList = albumAttributeValueVoList.stream().map(albumAttributeValue -> {
                // 创建对象
                AttributeValueIndex attributeValueIndex = new AttributeValueIndex();
                // 属性赋值
                attributeValueIndex.setValueId(albumAttributeValue.getValueId());
                attributeValueIndex.setAttributeId(albumAttributeValue.getAttributeId());
                return attributeValueIndex;
            }).collect(Collectors.toList());
            albumInfoIndex.setAttributeValueIndexList(attributeValueIndexList);
            // 返回数据
            return albumInfo;
        }, threadPoolExecutor).exceptionally(ex -> {
            System.out.println(ex.getMessage());
            return new AlbumInfo();
        });

        // 异步获取分类信息
        CompletableFuture<Void> categoryCompletableFuture = albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
            // 调用远程接口获取分类视图
            Result<BaseCategoryView> categoryViewResult = categoryFeignClient.getBaseCategoryView(albumInfo.getCategory3Id());
            // 断言远程调用结果不为空
            Assert.notNull(categoryViewResult, "远程调用获取分类视图失败");
            BaseCategoryView baseCategoryView = categoryViewResult.getData();
            albumInfoIndex.setCategory1Id(baseCategoryView.getCategory1Id());
            albumInfoIndex.setCategory2Id(baseCategoryView.getCategory2Id());
        }, threadPoolExecutor).exceptionally(ex -> {
            System.out.println(ex.getMessage());
            return null;
        });

        // 异步获取用户信息
        CompletableFuture<Void> userCompletableFuture = albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
            // 调用远程接口获取用户信息
            Result<UserInfoVo> userInfoResult = userInfoFeignClient.getUserInfo(albumInfo.getUserId());
            // 断言远程调用结果不为空
            Assert.notNull(userInfoResult, "远程调用用户信息失败");
            UserInfoVo userInfoVo = userInfoResult.getData();
            // 断言用户信息不为空
            Assert.notNull(userInfoVo, "远程调用失败");
            albumInfoIndex.setAnnouncerName(userInfoVo.getNickname());
        }, threadPoolExecutor).exceptionally(ex -> {
            System.out.println(ex.getMessage());
            return null;
        });


        // 异步获取专辑统计值
        CompletableFuture<Void> statCompletableFuture = albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
            // 调用Feign客户端获取专辑统计信息
            Result<AlbumStatVo> statVoResult = albumInfoFeignClient.getStat(albumId);
            // 确保统计信息结果不为空
            Assert.notNull(statVoResult, "远程调用统计值失败");
            // 提取统计信息
            AlbumStatVo albumStatVo = statVoResult.getData();
            // 更新专辑信息索引的统计数值
            albumInfoIndex.setPlayStatNum(albumStatVo.getPlayStatNum());
            albumInfoIndex.setBuyStatNum(albumStatVo.getBuyStatNum());
            albumInfoIndex.setCommentStatNum(albumStatVo.getCommentStatNum());
            albumInfoIndex.setSubscribeStatNum(albumStatVo.getSubscribeStatNum());
            // 设置一个随机的热度分数
            albumInfoIndex.setHotScore((double) new Random().nextInt(10000));
        }, threadPoolExecutor).exceptionally(ex -> {
            // 处理异常情况
            System.out.println(ex.getMessage());
            return null;
        });

        // 设置随机的播放、购买、评论和订阅统计数以及热度分数
//        albumInfoIndex.setPlayStatNum(new Random().nextInt(100000));
//        albumInfoIndex.setBuyStatNum(new Random().nextInt(100000));
//        albumInfoIndex.setCommentStatNum(new Random().nextInt(100000));
//        albumInfoIndex.setSubscribeStatNum(new Random().nextInt(100000));
//        albumInfoIndex.setHotScore((double) new Random().nextInt(10000));

        // 等待所有异步任务完成
        // 通常：get方法只调用一次! 应该将方法放在最后
        try {
            System.out.println("category:" + categoryCompletableFuture.get());
            System.out.println("user:" + userCompletableFuture.get());
            if (ObjectUtils.isEmpty(albumInfoCompletableFuture.get())) {
                log.info("远程调用失败");
                return;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        // 确保所有异步操作都已完成，多任务组合
        CompletableFuture.allOf(
                albumInfoCompletableFuture,
                categoryCompletableFuture,
                userCompletableFuture,
                statCompletableFuture
        ).join();

        // 将数据插入到ES中
        log.info("将数据插入到es中");
        albumIndexRepository.save(albumInfoIndex);

        // 保存提词库
        // 赋值：专辑标题
        SuggestIndex suggestIndex = new SuggestIndex();
        suggestIndex.setId(UUID.randomUUID().toString().replaceAll("-",""));
        suggestIndex.setTitle(albumInfoIndex.getAlbumTitle());
        suggestIndex.setKeyword(new Completion(new String[]{albumInfoIndex.getAlbumTitle()}));
        suggestIndex.setKeywordPinyin(new Completion(new String[]{PinYinUtils.toHanyuPinyin(albumInfoIndex.getAlbumTitle())}));
        suggestIndex.setKeywordSequence(new Completion(new String[]{PinYinUtils.getFirstLetter(albumInfoIndex.getAlbumTitle())}));
        suggestIndexRepository.save(suggestIndex);

        // 赋值：专辑简介
        SuggestIndex suggestIndexIntro = new SuggestIndex();
        suggestIndexIntro.setId(UUID.randomUUID().toString().replaceAll("-",""));
        suggestIndexIntro.setTitle(albumInfoIndex.getAlbumIntro());
        suggestIndexIntro.setKeyword(new Completion(new String[]{albumInfoIndex.getAlbumIntro()}));
        suggestIndexIntro.setKeywordPinyin(new Completion(new String[]{PinYinUtils.toHanyuPinyin(albumInfoIndex.getAlbumIntro())}));
        suggestIndexIntro.setKeywordSequence(new Completion(new String[]{PinYinUtils.getFirstLetter(albumInfoIndex.getAlbumIntro())}));
        suggestIndexRepository.save(suggestIndexIntro);

        // 赋值: 作者
        SuggestIndex suggestIndexAnnouncerName = new SuggestIndex();
        suggestIndexAnnouncerName.setId(UUID.randomUUID().toString().replaceAll("-",""));
        suggestIndexAnnouncerName.setTitle(albumInfoIndex.getAnnouncerName());
        suggestIndexAnnouncerName.setKeyword(new Completion(new String[]{albumInfoIndex.getAnnouncerName()}));
        suggestIndexAnnouncerName.setKeywordPinyin(new Completion(new String[]{PinYinUtils.toHanyuPinyin(albumInfoIndex.getAnnouncerName())}));
        suggestIndexAnnouncerName.setKeywordSequence(new Completion(new String[]{PinYinUtils.getFirstLetter(albumInfoIndex.getAnnouncerName())}));
        suggestIndexRepository.save(suggestIndexAnnouncerName);
    }

    /**
     * @author WeakMoon
     * @date 2025/02/25 18:56:36
     * 专辑下架
     * 本方法用于将指定的专辑从系统中删除。它通过调用albumIndexRepository的deleteById方法，
     * 传递专辑ID作为参数，以实现根据ID删除专辑的功能。
     * @param albumId 需要下架的专辑的唯一标识符
     */
    @Override
    public void lowerAlbum(Long albumId) {
        albumIndexRepository.deleteById(albumId);
    }

    /**
     * @author WeakMoon
     * @date 2025/02/26 20:56:58
     * 检索功能
     */
    @Override
    public AlbumSearchResponseVo search(AlbumIndexQuery albumIndexQuery) {
        // 构建DSL查询请求
        SearchRequest searchRequest = this.queryBuildDsl(albumIndexQuery);

        // 执行dsl 语句
        SearchResponse<AlbumInfoIndex> searchResponse = null;

        try {
            // 执行Elasticsearch搜索请求
            searchResponse = elasticsearchClient.search(searchRequest, AlbumInfoIndex.class);
        } catch (IOException e) {
            // 捕获IO异常并将其转换为运行时异常
            throw new RuntimeException(e);
        }

        // 解析搜索结果数据
        AlbumSearchResponseVo searchResponseVo = this.parseResultData(searchResponse);
        // 设置搜索结果的总记录数
        searchResponseVo.setTotal(searchResponse.hits().total().value());
        // 设置搜索结果的每页记录数
        searchResponseVo.setPageSize(albumIndexQuery.getPageSize());
        // 设置搜索结果的当前页码
        searchResponseVo.setPageNo(albumIndexQuery.getPageNo());
        // 计算并设置总页数
        Long totalPages = (searchResponseVo.getTotal() + searchResponseVo.getPageSize() -1) / searchResponseVo.getPageSize();
        searchResponseVo.setTotalPages(totalPages);
        // 返回搜索结果对象
        return searchResponseVo;
    }


    /**
     * @author WeakMoon
     * @date 2025/02/27 14:22:50
     * 解析结果数据
     */
    private AlbumSearchResponseVo parseResultData(SearchResponse<AlbumInfoIndex> searchResponse) {
        // 创建一个专辑搜索响应对象来存储解析后的数据
        AlbumSearchResponseVo albumSearchResponseVo = new AlbumSearchResponseVo();

        // 将搜索响应中的每个命中项转换为专辑信息索引视图对象
        List<AlbumInfoIndexVo> albumInfoIndexVoList = searchResponse.hits().hits().stream().map(hit -> {

            // 创建一个专辑信息索引视图对象
            AlbumInfoIndexVo albumInfoIndexVo = new AlbumInfoIndexVo();

            // 从命中项中获取专辑信息索引对象，并复制属性到视图对象
            AlbumInfoIndex albumInfoIndex = hit.source();
            BeanUtils.copyProperties(albumInfoIndex,albumInfoIndexVo);

            // 如果命中项有高亮标题，则设置高亮后的专辑标题
            if (hit.highlight().get("albumTitle") != null){
                String albumTitle = hit.highlight().get("albumTitle").get(0);
                albumInfoIndexVo.setAlbumTitle(albumTitle);
            }

            // 返回转换后的专辑信息索引视图对象
            return albumInfoIndexVo;
        }).collect(Collectors.toList());

        // 将转换后的专辑信息列表设置到搜索响应对象中
        albumSearchResponseVo.setList(albumInfoIndexVoList);

        // 返回填充好的专辑搜索响应对象
        return albumSearchResponseVo;
    }


    /**
     * @author WeakMoon
     * @date 2025/02/26 21:09:19
     * 构建dsl语句
     */
    private SearchRequest queryBuildDsl(AlbumIndexQuery albumIndexQuery) {
        // 通过Builder()创建对象
        SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder();
        // 指定索引名称
        searchRequestBuilder.index("albuminfo");
        // 创建BoolQuery构建器，用于构建复杂的查询条件
        BoolQuery.Builder boolQuerybuilder = new BoolQuery.Builder();

        // 根据关键词构建查询条件
        if (!StringUtils.isEmpty(albumIndexQuery.getKeyword())){
            boolQuerybuilder.should(s -> s.match(m -> m.field("albumTitle").query(albumIndexQuery.getKeyword())))
                    .should(s -> s.match(m -> m.field("albumIntro").query(albumIndexQuery.getKeyword())))
                    .should(s -> s.match(m -> m.field("announcerName").query(albumIndexQuery.getKeyword())));
            // 设置高亮显示
            searchRequestBuilder.highlight(h -> h.fields("albumTitle",f -> f.preTags("<span style=color:red>").postTags("</span>")));
        }

        // 根据一级分类ID构建查询条件
        if (!StringUtils.isEmpty(albumIndexQuery.getCategory1Id())){
            boolQuerybuilder.filter(f -> f.term(t -> t.field("category1Id").value(albumIndexQuery.getCategory1Id())));
        }
        // 根据二级分类ID构建查询条件
        if (!StringUtils.isEmpty(albumIndexQuery.getCategory2Id())){
            boolQuerybuilder.filter(f -> f.term(t -> t.field("category2Id").value(albumIndexQuery.getCategory2Id())));
        }
        // 根据三级分类ID构建查询条件
        if (!StringUtils.isEmpty(albumIndexQuery.getCategory3Id())){
            boolQuerybuilder.filter(f -> f.term(t -> t.field("category3Id").value(albumIndexQuery.getCategory3Id())));
        }

        // 根据属性列表构建查询条件
        List<String> attributeList = albumIndexQuery.getAttributeList();
        if (!CollectionUtils.isEmpty(attributeList)){
            for (String attr : attributeList) {
                String[] split = attr.split(":");
                if (split != null && split.length == 2){
                    boolQuerybuilder.filter(f -> f.nested(n -> n.path("attributeValueIndexList")
                            .query(q -> q.bool(b -> b.must(m -> m.match(m1 -> m1.field("attributeValueIndexList.attributeId").query(split[0])))
                                    .must(m -> m.match(m1 -> m1.field("attributeValueIndexList.valueId").query(split[1])))))));
                }
            }
        }

        // 根据排序参数构建排序条件
        String order = albumIndexQuery.getOrder();
        if (!StringUtils.isEmpty(order)){
            String[] split = order.split(":");
            if (split != null && split.length == 2){
                String field = "";
                switch (split[0]){
                    case "1":
                        field = "hotScore";
                        break;
                    case "2":
                        field = "playStatNum";
                        break;
                    case "3":
                        field = "createTime";
                        break;
                }
                String finalField = field;
                searchRequestBuilder.sort(s -> s.field(f -> f.field(finalField).order("asc".equals(split[1]) ? SortOrder.Asc : SortOrder.Desc)));
            }
        }
        // 计算分页参数
        int from = (albumIndexQuery.getPageNo() - 1) * albumIndexQuery.getPageSize();
        searchRequestBuilder.from(from);
        searchRequestBuilder.size(albumIndexQuery.getPageSize());

        // 构建最终的BoolQuery
        BoolQuery boolQuery = boolQuerybuilder.build();
        // 将BoolQuery应用到SearchRequest
        searchRequestBuilder.query(boolQuery._toQuery());

        // 构建并返回SearchRequest对象
        SearchRequest searchRequest = searchRequestBuilder.build();
        // 打印dsl语句
        System.out.println("dsl:" + searchRequest.toString());

        return searchRequest;
    }
}
